package com.nbut.filesystem;

import javax.swing.JFileChooser;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;

/**
 * 文件系统的主类
 */
public class FileSystem {
    //文件系统的根目录
    private String baseAddr;
    //用户文件目录
    private String userFileAddr;
    //登陆系统
    private Login login;
    //登陆的状态，true表示已登录，false表示未登录
    private boolean isLogin = false;
    private Scanner in;
    //接收的用户输入的命令
    private String[] orders;
    //用户实体
    private User user;
    //初始化文件系统
    public FileSystem(){
        //获取电脑中我的文档的绝对路径，并加入文件系统路径
        baseAddr = new JFileChooser().getFileSystemView().getDefaultDirectory().toString()+ "\\FileSystem\\";
        //尝试创建文件系统主目录
        new File(baseAddr).mkdirs();
        //初始化登陆系统
        login = new Login(baseAddr);
        //初始化获取命令行输入
        in = new Scanner(System.in);
    }

    /**
     * 程序主要的执行方法
     * 接收用户的输入，调用对应的方法
     */
    public void launch(){
        //输出欢迎文字
        System.out.println("欢迎来到文件管理系统");
        System.out.println("请先使用login命令进行登陆,若您没有账号可以使用register命令注册账号");
        System.out.println("若想要获得详细帮助请输入 help 或 ? ");

        //主要的获取用户输入的循环
        exit:while(true){
            //获取命令并以空格进行分隔
            String order = in.nextLine();
            orders = order.split("\\s");
            //根据是否登陆来决定获取的命令
            if(!isLogin) {
                //根据第一位指令来决定要进行的操作
                switch (orders[0]) {
                    case "?":
                    case "help":
                        help();
                        break;
                    case "login":
                        login();
                        break;
                    case "register":
                        register();
                        break;
                    case "exit":
                        break exit;
                    case "dir":
                    case "create":
                    case "delete":
                    case "open":
                    case "read":
                    case "write":
                        System.out.println("请先登陆!");
                        break;
                    default:
                        System.out.println("\""+order+"\""+ "不是一个可执行的命令!");
                }
            }else {
                switch (orders[0]) {
                    case "?":
                    case "help":
                        help();
                        break;
                    case "login":
                    case "register":
                        System.out.println("您已登陆");
                        break;
                    case "dir":
                        dir();
                        break;
                    case "create":
                        create();
                        break;
                    case "delete":
                        delete();
                        break;
                    case "open":
                        open();
                        break;
                    case "read":
                        read();
                        break;
                    case "write":
                        write();
                        break;
                    case "exit":
                       if(exit()) {
                           break exit;
                       }else {
                           System.out.println("用户文件存在错误，退出失败!");
                           break;
                       }
                    default:
                        System.out.println("\""+order+ "\""+ "不是一个可执行的命令!");
                }
            }
        }
        System.out.println("bye!");
    }
    //输出帮助信息
    public void help(){
        System.out.println("------------------命令列表-----------------");
        System.out.println("   login 用户名 密码 ················登入系统");
        System.out.println("   register 用户名 密码 ·············注册账号");
        System.out.println("   dir ·························文件目录列表");
        System.out.println("   crate 文件名.扩展名 ···············创建文件");
        System.out.println("   delete 文件名.扩展名 ··············删除文件");
        System.out.println("   open 文件名.扩展名 ················打开文件");
        System.out.println("   read 文件名.扩展名 ················读取文件");
        System.out.println("   write 文件名.扩展名 写入内容 ········写入文件");
    }
    //登陆的方法
    public void login(){
        //获取用户输入的用户名和密码
        String username = getUsername();
        String password = getPassword();
        try {
            //将用户名和密码传入方法中，获取用户对象
            user = login.login(username,password);
            if(user != null){//若用户不为空，就是登陆成功
                //更新用户文件目录的绝对路劲
                userFileAddr = baseAddr + "file\\" + username + "\\";
                //将登陆状态置为已登陆
                isLogin = true;
                //输入提示信息
                System.out.println("登陆成功！");
                System.out.println("欢迎您,用户"+username);
                System.out.println("若想要获得详细帮助请输入 help 或 ? ");
            }else{
                System.out.println("登陆失败，请检查用户名和密码！");
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //注册方法
    public void register(){
    	//获取用户输入
        String username = getUsername();
        String password = getPassword();

        try {
            if(login.register(username,password)){
                //更新用户文件目录的绝对路劲
                userFileAddr = baseAddr + "file\\" + username + "\\";
                if(new File(userFileAddr).mkdirs())//创建用户文件目录
                    System.out.println("注册成功!");
                else
                    System.out.println("注册成功，文件目录已存在!");
            }else{
                System.out.println("注册失败，用户已存在！");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //列出用户的文件目录列表
    public void dir(){
        //获取用户文件表
        HashMap<String,String> userLib = user.getUserFileList().getLibMap();
        //获取用户文件表的KeySet（虚拟文件名的集合）
        Set<String> fileList = userLib.keySet();
        //遍历整个集合输出文件名
        for(String s:fileList){
            System.out.println(s);
        }
        //输出有多少个文件
        if(fileList.size() > 0){
            System.out.println("一共有"+fileList.size()+"个文件");
        }else{
            System.out.println("文件目录是空的");
        }
    }
    //创建文件
    public void create(){
        //获取虚拟文件名
        String fileName = getFileName();
        try {
            if(FileAction.create(userFileAddr,fileName,user)){
                System.out.println("创建"+fileName+"成功!");
            }else{
                System.out.println("创建失败!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //删除文件
    public void delete(){
        //获取虚拟文件名
        String fileName = getFileName();
        if(FileAction.delete(userFileAddr,fileName,user)){
            System.out.println("删除"+fileName+"成功!");
        }else {
            System.out.println("删除"+fileName+"失败!");
        }
    }
    //打开文件
    public void open(){
        //获取虚拟文件名
        String fileName = getFileName();
        try {
            File realFile = getRealFile(fileName);
            if(realFile.exists()) {
            	FileAction.open(realFile);
            }else {
            	System.out.println("文件不存在！");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件打开失败！");
        }
    }
    //读取文件
    public void read(){
        //获取虚拟文件名
        String fileName = getFileName();
        try {
            //获取真实文件
            File realFile = getRealFile(fileName);
            //判断文件是否存在
            if(realFile.exists()) {
                //调用读取方法，接收读取的数据
	            String content = FileAction.read(realFile);
	            System.out.println("读取成功，内容为:");
	            System.out.println(content);
            }else {
            	System.out.println("文件不存在！");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取失败!");
        }
    }
    //写入文件
    public void write(){
        //获取虚拟文件名
        String fileName = getFileName();
        //获取用户输入的内容
        String content = getInputString();
        try {
            //获取真实文件
            File realFile = getRealFile(fileName);
            if(realFile.exists()) {
                //调用方法，写入数据
	            FileAction.write(realFile,content);
	            System.out.println("写入完成!");
            }else {
            	System.out.println("文件不存在！");
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("写入失败!");
        }
    }

    public boolean exit(){
        //退出系统时更新用户文件表并保存在硬盘上
        //先删除旧的
        if(UserAction.deleteUser(baseAddr+"User\\",user)){
            try {
                //再创建新的
                UserAction.createUser(baseAddr+"User\\",user);
                System.out.println("用户表更新成功");
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("用户文件表更新失败!");
            }
        }else {
            System.out.println("用户文件表删除失败!");
        }
        return false;
    }

    /**
     * 传入虚拟文件名，获取真实文件名
     * @param virtualFileName 虚拟文件名
     * @return 真实文件名
     */
    private File getRealFile(String virtualFileName){
        //查询用户文件表，获取真实文件名
        String realName = user.getUserFileList().getLibMap().get(virtualFileName);
        //拼接为真实文件的绝对路径
        return new File(userFileAddr+realName);
    }

//接下来的这些方法均为从用户输入的命令中获取某些数据
    /**
     * 获取用户输入的文件名
     * @return 文件名
     */
    private String getFileName(){
        String fileName;
        if(orders.length >= 2){
            fileName = orders[1];
        }else{
            System.out.print("文件完整名:");
            fileName = in.nextLine();
        }
        return fileName;
    }

    /**
     * 获取用户输入的要写入文件的内容
     * @return 用户输入的内容
     */
    private String getInputString(){
        String content;
        if(orders.length <= 2){
            System.out.print("要写入文件的内容为:");
            content = in.nextLine();
        }else{
            content = orders[2];
        }
        return content;
    }

    /**
     * 获取用户名
     * @return 用户名
     */
    private String getUsername(){
        String username;
        if(orders.length == 1){
            System.out.print("用户名:");
            username = in.nextLine();
        }else{
            username = orders[1];
        }
        return username;
    }

    /**
     * 获取密码
     * @return 密码
     */
    private String getPassword(){
        String password;
        if(orders.length <= 2){
            System.out.print("密码:");
            password = in.nextLine();
        }else{
            password = orders[2];
        }
        return password;
    }
}
